package com.mmallbe.task;

import com.mmallbe.common.Const;
import com.mmallbe.common.RedisPool;
import com.mmallbe.service.IOrderService;
import com.mmallbe.util.PropertiesUtil;
import com.mmallbe.util.RedisPoolUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import javax.annotation.PreDestroy;

@Component
@Slf4j
public class CloseOrderTask {

    @Autowired
    private IOrderService iOrderServiceImpl;

    @PreDestroy
    public void deLock(){
        RedisPoolUtil.del(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
    }

    //@Scheduled(cron="*/10 */1 * * * ?")//每分钟（每隔1分钟的整数倍
    public void closeOrderTaskV1(){
        log.info("关闭订单定时任务启动");
        int hour = Integer.parseInt(PropertiesUtil.getProperty("close.order.task.time.hour","2"));
        iOrderServiceImpl.closeOrder(hour);
        log.info("关闭订单定时任务结束");
    }

    //@Scheduled(cron="*/10 */1 * * * ?")//每分钟（每隔1分钟的整数倍
    public void closeOrderTaskV2(){
        log.info("关闭订单定时任务启动");
        long lockTime = Long.parseLong((PropertiesUtil.getProperty("lock.timeout","5000")));
        Long setnxResult = RedisPoolUtil.setnx(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTime));

        if(setnxResult != null && setnxResult.intValue() == 1){
            //如果返回值是1 ，代表设置成功，获取锁
            closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
        }else {
            log.info("没有获得分布式锁：{}", Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
        }
        log.info("关闭订单定时任务结束");
    }
    @Scheduled(cron="*/10 */1 * * * ?")//每分钟（每隔1分钟的整数倍
    public void closeOrderTaskV3(){
        log.info("关闭订单定时任务启动");
        long lockTime = Long.parseLong((PropertiesUtil.getProperty("lock.timeout","5000")));
        Long setnxResult = RedisPoolUtil.setnx(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTime));

        if(setnxResult != null && setnxResult.intValue() == 1){
            //如果返回值是1 ，代表设置成功，获取锁
            closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
        }else {
            log.info("没有获得分布式锁：{}", Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
            //未获取到锁，继续判断，判断时间戳，看是否可以重置获取到锁
            String lockValueStr = RedisPoolUtil.get(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
            if(lockValueStr != null && System.currentTimeMillis() > Long.parseLong(lockValueStr)){

                String getSetResult = RedisPoolUtil.getSet(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTime));
                //再次用当前时间戳getSet。
                //返回给定的key的旧值 --》 旧值判断，是否可以获得锁
                //当key没有旧值时，即key不存在时，返回nil=》 获取锁
                //这里我们set了一个新的value值，获取旧的值
                if(getSetResult == null || (getSetResult != null && StringUtils.equals(lockValueStr,getSetResult))){
                    //真正获取到锁
                    closeOrder(Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
                }else{
                    log.info("没有获得分布式锁：{}", Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
                }
            }else{
                log.info("没有获得分布式锁：{}", Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK);
            }
        }
        log.info("关闭订单定时任务结束");
    }


    private void closeOrder(String lockName){
        RedisPoolUtil.expire(lockName, 5); // 有效期5秒，防止死锁
        log.info("获取{} ,ThreadName:{} ",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,Thread.currentThread().getName());
        int hour = Integer.parseInt(PropertiesUtil.getProperty("close.order.task.time.hour","2"));
        iOrderServiceImpl.closeOrder(hour);
        RedisPoolUtil.del(lockName); // 有效期50秒，防止死锁
        log.info("释放{} ,ThreadName:{} ",Const.REDIS_LOCK.CLOSE_ORDER_TASK_LOCK,Thread.currentThread().getName());
        log.info("===================================");
    }


}
